/**
 * 原型对象
 *  ● 构造函数的 prototype 属性，被称为构造函数的原型对象
 *  ● 原型对象的 constructor 属性，指向它对应的构造函数
 *  ● 给构造函数的 prototype 重新赋值时，应该注意 constructor 属性
 *  ● 实例对象之间共享原型对象的成员
 *
 * 对象原型
 *  ● 实例对象的 __proto__ 属性，被称为实例对象的对象原型
 *  ● 实例对象的 __proto__ 指向创建它的构造函数的 prototype
 *
 * 关系
 *  ● 定义一个构造函数 Fn
 *  ● Object 和 Function 是内置的构造函数
 *  ● Fn 和 Object 是 Function 的实例
 *  ● Fn 和 Function 的原型对象是 Object 的实例
 */
function Fn() {}
Fn.prototype.prototypeFn = function () {
  console.log('prototypeFn')
}
var fn = new Fn(),
  fn2 = new Fn()

// 构造函数的 prototype 属性，被称为构造函数的原型对象
console.log(Fn.prototype)

// 原型对象的 constructor 属性，指向它对应的构造函数
console.log(Fn.prototype.constructor)

// 给构造函数的 prototype 重新赋值时，应该注意 constructor 属性
// Fn.prototype = { constructor: Fn }

// 实例对象之间共享原型对象的成员
console.log(fn.prototypeFn === fn2.prototypeFn) // true

// 实例对象的 __proto__ 属性，被称为实例对象的对象原型
console.log(fn.__proto__)

// 实例对象的 __proto__ 指向创建它的构造函数的 prototype
console.log(Fn.prototype === fn.__proto__) // true

// 关系 >>>
console.log(Fn.__proto__ === Function.prototype)
console.log(Function.prototype.__proto__ === Object.prototype)
console.log(Object.prototype.__proto__ === null)

console.log(fn.__proto__ === Fn.prototype)
console.log(Fn.prototype.__proto__ === Object.prototype)
console.log(Object.prototype.__proto__ === null)

console.log(Object.__proto__ === Function.prototype)
// 关系 <<<
